﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace libSyllabus.Model
{
    /// <summary>
    /// This is Semester entity class, which represents an entry in the Semesters table.
    /// </summary>
    /// <remarks>
    /// For now, Semester table contains following columns:
    ///  - ID                : Auto Generated Index (Number)
    ///  - Title            : Semester Name (String)
    ///  - SemesterYear             : Year of the semester (Number)
    ///  - StartDate      : Date when the semester starts (DateTime)
    ///  - EndDate        : Date when the semester ends (DateTime)
    ///  
    /// Property Change Notification is taken care of in the base class
    /// </remarks>
    [Table(Name = "Semesters")]
    public sealed class SemesterEntity : EntityBase
    {
        #region Constants

        // Column Name Constants
        public const string SEMESTER_ID = "ID";
        private const string SEMESTER_NAME = "Title"; // Name is reserved in SQL Server
        private const string SEMESTER_YEAR = "SemesterYear";
        private const string SEMESTER_STARTDATE = "StartDate";
        private const string SEMESTER_ENDDATE = "EndDate";

        #endregion

        #region Constructors

        public SemesterEntity()
        {
            m_courses = new EntitySet<CourseEntity>();
        }

        #endregion

        #region Fields

        // Fields and mapping to database columns
        [Column(Name = SEMESTER_ID, IsPrimaryKey = true, CanBeNull = false, IsDbGenerated = true, DbType = "INT NOT NULL Identity")]
        private Int32 m_id;

        [Column(Name = SEMESTER_NAME, CanBeNull = false)]
        private String m_name;

        [Column(Name = SEMESTER_YEAR, CanBeNull = false)]
        private UInt16 m_year;

        [Column(Name = SEMESTER_STARTDATE, CanBeNull = false)]
        private DateTime m_startDate;

        [Column(Name = SEMESTER_ENDDATE, CanBeNull = false)]
        private DateTime m_endDate;

        // Relationship to CourseEntity
        private EntitySet<CourseEntity> m_courses;

        #endregion

        #region Properties

        // Encapsulation
        public Int32 ID
        {
            // No setter, this property is readonly
            get
            {
                return m_id;
            }
        }

        public String Title
        {
            get
            {
                return m_name;
            }
            set
            {
                // Skip this operation if the new value is same as existing value
                if (m_name != value)
                {
                    // notify subscribers that this property is going to be changed
                    RaisePropertyChanging(SEMESTER_NAME);
                    m_name = value;
                    // notify subscribers that this property was changed
                    RaisePropertyChanged(SEMESTER_NAME);
                }
            }
        }

        public UInt16 Year
        {
            get
            {
                return m_year;
            }
            set
            {
                // Skip this operation if the new value is same as existing value
                if (m_year != value)
                {
                    // notify subscribers that this property is going to be changed
                    RaisePropertyChanging(SEMESTER_YEAR);
                    m_year = value;
                    // notify subscribers that this property was changed
                    RaisePropertyChanged(SEMESTER_YEAR);
                }
            }
        }

        public DateTime StartDate
        {
            get
            {
                return m_startDate;
            }
            set
            {
                // Skip this operation if the new value is same as existing value
                if (m_startDate != value)
                {
                    // notify subscribers that this property is going to be changed
                    RaisePropertyChanging(SEMESTER_STARTDATE);
                    m_startDate = value;
                    // notify subscribers that this property was changed
                    RaisePropertyChanged(SEMESTER_STARTDATE);
                }
            }
        }

        public DateTime EndDate
        {
            get
            {
                return m_endDate;
            }
            set
            {
                // Skip this operation if the new value is same as existing value
                if (m_endDate != value)
                {
                    // notify subscribers that this property is going to be changed
                    RaisePropertyChanging(SEMESTER_ENDDATE);
                    m_endDate = value;
                    // notify subscribers that this property was changed
                    RaisePropertyChanged(SEMESTER_ENDDATE);
                }
            }
        }

        [Association(Storage = "m_courses", OtherKey = CourseEntity.COURSE_SEMESTERID)]
        public EntitySet<CourseEntity> Courses
        {
            // This property is "readonly"
            // We can't assign it, but it's possible to manipulate
            // the encapsulated object since it's passed by reference
            get
            {
                return m_courses;
            }
        }

        #endregion
    }
}
